<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PLY Viewer</title>
    <style>
      body {
        margin: 0;
      }
      canvas {
        display: block;
      }
      .btn_wrapper {
        position: fixed;
        left: 5px;
        top: 5px;
      }
    </style>

    <script type="importmap">
      {
        "imports": {
          "three": "../three/v170/three.module.min.js",
          "three/addons/": "../three/v170/"
        }
      }
    </script>
  </head>
  <body>
    <div class="btn_wrapper">
      <button class="btn" onclick="resetCamera()">复位</button>
    </div>

    <script src="../static/layui/layui.js"></script>
    <script type="module">
      import * as THREE from "three";
      import { PLYLoader } from "three/addons/loaders/PLYLoader.js";
      import { OrbitControls } from "three/addons/controls/OrbitControls.js";

      // 复位
      window.resetCamera = () => {
        camera.position.set(0, 0, 10);
        controls.target.set(0, 0, 0);
        controls.update();
      };

      // 创建场景、相机和渲染器
      const scene = new THREE.Scene();
      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );
      const renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      // 添加坐标轴
      const axesHelper = new THREE.AxesHelper(5); // 参数表示坐标轴的长度
      scene.add(axesHelper);

      // 添加光源
      const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
      scene.add(ambientLight);
      const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 平行光
      directionalLight.position.set(1, 1, 1).normalize();
      scene.add(directionalLight);

      // 添加轨道控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true; // 启用阻尼效果
      controls.dampingFactor = 0.05;

      // 添加以下设置
      controls.enableZoom = true; // 启用缩放
      controls.enablePan = true;  // 启用平移
      controls.minDistance = 0.1; // 最小距离
      controls.maxDistance = 10;  // 最大距离
      controls.autoRotate = false; // 可以设置为 true 实现自动旋转
      controls.autoRotateSpeed = 2.0; // 自动旋转速度

      // 加载PLY文件
      const loader = new PLYLoader();
      loader.load(
        // "./test_upload.ply", // 文件路径
        // "http://127.0.0.1:3002/ply-youding.ply", //
        "http://127.0.0.1:3002/getFile?filename=youting_success.ply", //
        (geometry) => {
          /* 
          // 检查是否有顶点颜色
          if (geometry.attributes.color) {
            // 创建材质，使用顶点颜色
            const material = new THREE.PointsMaterial({
              size: 0.05,
              vertexColors: true  // 启用顶点颜色
            });
          } else {
            // 如果没有顶点颜色，使用默认颜色
            const material = new THREE.PointsMaterial({
              color: 0x00ff00,
              size: 0.05
            });
          }
          */
          // 创建材质
          const material = new THREE.PointsMaterial({
            // color: 0x00ff00, // 点颜色
            size: 0.05, // 点大小
            vertexColors: true,  // 启用顶点颜色
          });

          // 创建点云对象
          const points = new THREE.Points(geometry, material);
          scene.add(points);

          // 调整相机位置
          // camera.position.x = 0;
          // camera.position.y = 0;
          camera.position.z = 50;
          camera.lookAt(points.position);
        },
        (xhr) => {
          // 加载进度回调
          console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
        },
        (error) => {
          // 加载错误回调
          console.error("An error happened while loading the PLY file:", error);
        }
      );

      // 渲染循环
      function animate() {
        requestAnimationFrame(animate);
        controls.update(); // 更新控制器
        renderer.render(scene, camera);
      }
      animate();

      // 窗口大小调整时更新渲染器和相机
      window.addEventListener("resize", () => {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      });
    </script>
  </body>
</html>
